<?php

namespace Yolo\Captcha;

use GdImage;
use Yolo\Captcha\Core\CaptchaEngine;
use Yolo\Captcha\Core\CaptchaFactory;
use Yolo\Captcha\Core\CaptchaResult;
use Yolo\Captcha\Core\ImageCreator;

/**
 * A Captcha class for generating captcha images.
 * @author LUSHAOMING <lushaoming6@gmail.com>
 * @package Yolo\Captcha
 */
class Captcha
{
    /**
     * @var array $config Captcha config.
     */
    private static array $config = [];

    private ?CaptchaResult $result = null;

    /**
     * Create a captcha image.
     * @param bool $base64encode Whether to return the image data in base64 format.
     * @return false|GdImage|resource|string if $base64encode is true, a base64encode string will return, or an image resource identifier on success, false on errors.
     */
    public function createCaptcha(bool $base64encode = false)
    {
        $config = array_merge($this->getDefaultConfig(), self::$config);

        $engine = CaptchaFactory::getFactory($config['engine']);

        $this->result = $engine->create($config);

        $imageCreator = new ImageCreator($config);
        $image = $imageCreator->create($this->result->getTextData());

        if ($base64encode) {
            ob_start();
            imagepng($image);
            $imageData = ob_get_clean();
            $this->destroyCaptcha($image);

            return 'data:image/png;base64,' . base64_encode($imageData);
        } else {
            return $image;
        }
    }

    /**
     * Get captcha answer.
     * @return string
     */
    public function getCaptchaAnswer(): string
    {
        return $this->result->getAnswer();
    }

    /**
     * Destroy a captcha image.
     * @param $image
     * @return void
     */
    public function destroyCaptcha($image): void
    {
        imagedestroy($image);
    }

    /**
     * Get default config.
     * @return array
     */
    private function getDefaultConfig(): array
    {
        return [
            'height' => 50,
            'width' => 250,
            'length' => 6,
            'font' => __DIR__ . '/fonts/Arial.ttf',
            'fontSize' => 25,
            'quality' => 0, // 0-9
            'backgroundColor' => [255, 255, 255],
            'fontColor' => [0, 0, 0],
            'engine' => CaptchaEngine::CHARACTER,
        ];
    }

    /**
     * Set config.
     * @param array $config
     * @return void
     */
    public static function setConfig(array $config): void
    {
        self::$config = $config;
    }
}
